﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ObjectBuilder;
using SimilarityScoring;
using System.Threading;

namespace DesignPaternFinder
{
    public partial class Form1 : Form
    {
        private string fileName;
        private Parser parser;
        private Similarity sim;
        private bool loadOk = false;
        private Form2 matrices;
        public Form1()
        {
            InitializeComponent();
        }

        private void openBtn_Click(object sender, EventArgs e)
        {
            parser = new Parser();
            remItems();
            openFileDialog1.ShowDialog();
            fileName = openFileDialog1.FileName;
            parser.Assembly = fileName;
            parser.parse();
            parser.buildMatrix();
            foreach (Item it in parser.ItemArray)
            {
                assemblyList.Items.Add(it.Name);
            }
            genBtn.Enabled = true;
            ascBtn.Enabled = true;
            loadOk = true;
            if (patternBox.SelectedIndex >= 0 && loadOk) vypocetBtn.Enabled = true;
            else vypocetBtn.Enabled = false;
        }

        private void remItems()
        {
            assemblyList.Items.Clear();
        }
        private void patternBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (patternBox.SelectedIndex >= 0 && loadOk) vypocetBtn.Enabled = true;
            else vypocetBtn.Enabled = false;
            if (patternBox.SelectedIndex >= 0)
            {
                button1.Enabled = true;
            }
        }

        private void genBtn_Click(object sender, EventArgs e)
        {
            matrices = new Form2(parser.Gen, parser.ItemArray.Select(x => x.Name).ToList<string>());
            matrices.Text = "Matice generalizace";
            matrices.ShowDialog();
        }

        private void ascBtn_Click(object sender, EventArgs e)
        {
            matrices = new Form2(parser.Asc, parser.ItemArray.Select(x => x.Name).ToList<string>());
            matrices.Text = "Matice asociace vzoru ";
            matrices.ShowDialog();
        }

        private void vypocetBtn_Click(object sender, EventArgs e)
        {
            sim = new Similarity();
            sim.Threshold =((double) numericUpDown1.Value)/1000;
            sim.CalculateCompleteEvent += new Similarity.CalculateComplete(sim_CalculateCompleteEvent);
            switch (patternBox.SelectedIndex)
            {
                case 0: { sim.calculate(parser, AbstractFactory.Gen, AbstractFactory.Asc); break; }
                case 1: { sim.calculate(parser, Adapter.Gen, Adapter.Asc); break; }
                case 2: { sim.calculate(parser, Bridge.Gen, Bridge.Asc); break; }
                case 3: { sim.calculate(parser, Decorator.Gen, Decorator.Asc); break; }
                case 4: { sim.calculate(parser, Factory.Gen, Factory.Asc); break; }
                case 5: { sim.calculate(parser, Kompozit.Gen, Kompozit.Asc); break; }
                case 6: { sim.calculate(parser, Observer.Gen, Observer.Asc); break; }
            }


        }

        void sim_CalculateCompleteEvent()
        {
            patternLabel.Text = "Zvolený vzor : ";
            scoreLabel.Text = "Skóre : ";
            MatrixCalculator.Calculator mc = new MatrixCalculator.Calculator();
            MessageBox.Show("Výpočet dokončen.\nGenConvergence = "+sim.IsGenConvergence+"\nAscConvergence = "+sim.IsAscConvergence, "Hotovo",
                MessageBoxButtons.OK, MessageBoxIcon.Information);
            richTextBox1.Text = "Výsledná matice generalizace :\n" + matrixToString(method(sim.GenScore)) +
                "\nVýsledná matice asociace :\n" + matrixToString(method(sim.AscScore)) +
                "\nVýsledná matice :\n" + matrixToString(method(sim.TotalScore));
            label1.Text = patternBox.SelectedItem.ToString();
            double score = sim.MaxScore();
           
            if (double.IsNaN(score)) score = 0;
            if (double.IsNegativeInfinity(score)) score = 0;
            if (double.IsPositiveInfinity(score)) score = 0;
            if (double.IsInfinity(score)) score = 0;
            label2.Text = sim.MaxScore().ToString();
            label3.Text = mc.GetAvg(sim.TotalScore).ToString();
            label4.Text = mc.GetMax(sim.TotalScore).ToString();
            tabControl1.SelectedIndex = 1;
            //if (score >= 0 && score < 0.5)
            //{
            //    label3.Text = "Zvolený návrhový vzor není obsažen\n v zadané assembly nebo nebyl detekován."; ;
            //}else if(score >= 0.5 && score < 0.65)
            //{
            //    label3.Text = "V assembly jsou obsaženy prvky\n návrhového vzoru, ale nevíme jistě jakého.";
            //}else if(score >= 0.65 && score <= 1)
            //{
            //    label3.Text = "Můžeme s jistotou říct že,\n zvolený návrhový vzor je obsažen v zadané assembly.";
            //}
        }
        public double[,] method(double[,] matrix)
        {
            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    if (double.IsNaN(matrix[i, j])) matrix[i, j] = 0;
                    if (double.IsNegativeInfinity(matrix[i, j])) matrix[i, j] = 0;
                    if (double.IsPositiveInfinity(matrix[i, j])) matrix[i, j] = 0;
                    if (double.IsInfinity(matrix[i, j])) matrix[i, j] = 0;
                }
            }
            return matrix;
        }
        string matrixToString(double[,] matrix)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < matrix.GetLength(0); i++)
            {
                for (int j = 0; j < matrix.GetLength(1); j++)
                {
                    sb.Append(" " + Math.Round(matrix[i, j], 2) * 100);
                }
                sb.Append("\n");
            }
            return sb.ToString();
        }

        private void patternGenBtn_Click(object sender, EventArgs e)
        {
            switch (patternBox.SelectedIndex)
            {
                case 0:
                    {
                        matrices = new Form2(AbstractFactory.Gen, AbstractFactory.PatternDesc);
                        matrices.Text = "Matice generalizace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 1:
                    {
                        matrices = new Form2(Adapter.Gen, Adapter.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 2:
                    {
                        matrices = new Form2(Bridge.Gen, Bridge.PatternDesc);
                        matrices.Text = "Matice generalizace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 3:
                    {
                        matrices = new Form2(Decorator.Gen, Decorator.PatternDesc);
                        matrices.Text = "Matice generalizace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 4:
                    {
                        matrices = new Form2(Factory.Gen, Factory.PatternDesc);
                        matrices.Text = "Matice generalizace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 5:
                    {
                        matrices = new Form2(Kompozit.Gen, Kompozit.PatternDesc);
                        matrices.Text = "Matice generalizace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 6:
                    {
                        matrices = new Form2(Observer.Gen, Observer.PatternDesc);
                        matrices.Text = "Matice generalizace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
            }
        }

        private void patternAscBtn_Click(object sender, EventArgs e)
        {
            switch (patternBox.SelectedIndex)
            {
                case 0:
                    {
                        matrices = new Form2(AbstractFactory.Asc, AbstractFactory.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 1:
                    {
                        matrices = new Form2(Adapter.Asc, Adapter.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 2:
                    {
                        matrices = new Form2(Bridge.Asc, Bridge.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 3:
                    {
                        matrices = new Form2(Decorator.Asc, Decorator.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 4:
                    {
                        matrices = new Form2(Factory.Asc, Factory.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 5:
                    {
                        matrices = new Form2(Kompozit.Asc, Kompozit.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 6:
                    {
                        matrices = new Form2(Observer.Asc, Observer.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            switch (patternBox.SelectedIndex)
            {
                case 0:
                    {
                        matrices = new Form2(AbstractFactory.Gen, AbstractFactory.Asc, AbstractFactory.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 1:
                    {
                        matrices = new Form2(Adapter.Gen, Adapter.Asc, Adapter.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 2:
                    {
                        matrices = new Form2(Bridge.Gen, Bridge.Asc, Bridge.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 3:
                    {
                        matrices = new Form2(Decorator.Gen, Decorator.Asc, Decorator.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 4:
                    {
                        matrices = new Form2(Factory.Gen, Factory.Asc, Factory.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 5:
                    {
                        matrices = new Form2(Kompozit.Gen, Kompozit.Asc, Kompozit.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
                case 6:
                    {
                        matrices = new Form2(Observer.Gen, Observer.Asc, Observer.PatternDesc);
                        matrices.Text = "Matice asociace vzoru " + patternBox.SelectedItem.ToString();
                        matrices.ShowDialog(); break;
                    }
            }
        }
    }
}
